package com.itheima.aspect;

import com.itheima.aspect.annotation.OperaLog;
import com.itheima.common.BaseContext;
import com.itheima.pojo.OperationLog;
import com.itheima.service.OperationService;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.reflect.Method;
import java.time.LocalDateTime;
import java.util.TimerTask;

@Component
@Aspect
public class OperationAspect {
    @Autowired
    private OperationService operationService;

    @Pointcut("@annotation(com.itheima.aspect.annotation.OperaLog)")
    public void operationMethod(){}

    @Around("operationMethod()")
    public Object operationLogHandle(ProceedingJoinPoint pjp){
        OperationLog operationLog = new OperationLog();

        //MethodSignature是Signature的子类，更具体
        MethodSignature signature = (MethodSignature) pjp.getSignature();
        Method method = signature.getMethod();
        //获取注解
        OperaLog annotation = method.getAnnotation(OperaLog.class);
        String value = annotation.value();
        String username = annotation.username();

        operationLog.setOperation_action(value);
        operationLog.setUser_id(BaseContext.getCurrentId());
        operationLog.setOperation_time(LocalDateTime.now());

        //获取目标方法的参数
        Object[] args = pjp.getArgs();
        Object result = null;
        try {
            //前置增强

            result = pjp.proceed(args);

            //后置增强

        } catch (Throwable e) {
            e.printStackTrace();
            //异常增强
            new AsyncManager().execute(new TimerTask() {
                @Override
                public void run() {
                    operationService.save(operationLog);
                }
            });
        } finally {
            //返回后增强
            new AsyncManager().execute(new TimerTask() {
                @Override
                public void run() {
                    operationService.save(operationLog);
                }
            });
        }
        return result;
    }
}
